﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.IO.Compression;
using Zzw;

namespace FictionsDownload.BLL
{
    /// <summary>
    /// Http相关的静态方法
    /// </summary>
    public class HttpHelper
    {
        /// <summary>
        /// Get方式获取url地址输出内容
        /// </summary>
        /// <param name="url">url</param>
        /// <param name="encoding">返回内容编码方式，例如：Encoding.UTF8</param>
        /// <returns></returns>
        public static string SendRequest(string url, Encoding encoding)
        {
            try
            {
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
                webRequest.Method = "GET";
                HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
                Stream stream;
                if (webResponse.ContentEncoding == "gzip")
                {
                    stream = new GZipStream(webResponse.GetResponseStream(), CompressionMode.Decompress);
                }
                else
                {
                    stream = webResponse.GetResponseStream();
                }
                StreamReader sr;
                switch (webResponse.CharacterSet)
                {
                    case "utf-8":
                        sr = new StreamReader(stream, Encoding.UTF8);
                        break;
                    case "ISO-8859-1":
                        sr = new StreamReader(stream, Encoding.GetEncoding("ISO-8859-1"));
                        return ConvertISO88591ToEncoding(sr.ReadToEnd(), Encoding.Default);
                    case "gbk":
                        sr = new StreamReader(stream, Encoding.Default);
                        break;
                    default:
                        sr = new StreamReader(stream, Encoding.Default);
                        break;
                }
                return sr.ReadToEnd();
            }
            catch(Exception ex)
            {
                var errorMsg = ex.Message;
                if(errorMsg == "正在中止线程。")
                {
                    return "";
                }
                else if(errorMsg == "远程服务器返回错误: (503) 服务器不可用。")
                {
                    return "";
                }
                else
                {
                    return "";
                }
            }
        }
        private static string ConvertISO88591ToEncoding(string srcString, Encoding dstEncode)
        {
            byte[] iso88591Byte = Encoding.GetEncoding("ISO-8859-1").GetBytes(srcString);
            //将原本存储ISO-8859-1的字节数组当成UTF8转换成目标编码(关键步骤)(偶尔需要GB2312,原因不明)
            Encoding srcEncoding = iso88591Byte.GetEncoding();
            byte[] dstBytes = Encoding.Convert(srcEncoding, dstEncode, iso88591Byte);
            char[] dstChars = new char[dstEncode.GetCharCount(dstBytes, 0, dstBytes.Length)];
            dstEncode.GetChars(dstBytes, 0, dstBytes.Length, dstChars, 0);//利用char数组存储字符
            string strResult = new string(dstChars);
            return strResult;
        }
        public static string DownloadHtml(string url)
        {
            string request = HttpHelper.SendRequest(url, Encoding.Default);
            if (request == "")
                return null;
            return request;

        }
        /// <summary>
        /// 分析Url，错误返回null，正确返回url或者主站。
        /// </summary>
        /// <param name="url"></param>
        /// <param name="auth"></param>
        /// <returns></returns>
        public static string UrlParse(string url, bool auth = false)
        {
            try
            {
                Uri uri = new Uri(url);
                if (auth)
                {
                    return uri.Scheme + "://" + uri.Authority;
                }
                else
                {
                    return url;
                }
            }
            catch(Exception ex)
            {
                if(ex.Message == "无效的 URI: 未能确定 URI 的格式。")
                {
                    return null;
                }
                else
                {
                    var temp = ex;
                    return null;
                }
            }
        }
    }
}
